﻿using NPortableEngine;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;

namespace NCache
{
    public class CacheEngine
    {
        public static string CacheFolder = "ImageDir";

        internal static async Task<Stream> QueueCacheImage(Uri uri)
        {
            TaskCompletionSource<Stream> tcs = new TaskCompletionSource<Stream>();
            Action<Stream> action = (Stream stream) =>
            {
                tcs.TrySetResult(stream);
            };

            CacheDeliver deliver = new CacheDeliver(uri,action);
            NTaskScheduler.Instance.QueueTask(deliver, new CacheDeliverExecutor());
            return await tcs.Task;
        }

        /// <summary>
        /// 缓存图片
        /// 1.判断图片存在
        /// 2.不存在下载
        /// 3.然会本地存储的地址
        /// </summary>
        /// <param name="uri"></param>
        internal static async Task<Stream> CacheImage(Uri uri)
        {
            return await CacheImage(uri.OriginalString, UriToFileName(uri.OriginalString), CacheFolder).ConfigureAwait(false);
        }

        /// <summary>
        /// 缓存图片
        /// </summary>
        /// <param name="url">Remoate Image Url</param>
        /// <param name="fileName">The ImageName you like</param>
        /// <param name="folderName">The Image SavePath support 'Shared/ShellContent/SecondTileDir'</param>
        /// <returns>返回</returns>
        public static async Task<Stream> CacheImage(string url,string fileName, string folderName)
        {
            Stream stream = null;
            try
            {
                bool exists = await StorageHelper.Exists(folderName, fileName).ConfigureAwait(false);
                if (!exists)
                {
                    //Debug.WriteLine("Download from web mageurl:" + uri.ToString() + "-----------------");
                    stream = await DownloadFileAsync(url,fileName,folderName).ConfigureAwait(false);
                }
                else
                {
                    //Debug.WriteLine("load from local:" + uri.ToString() + "-----------------");
                    byte[] byteArr = await StorageHelper.GetFileStreamAysnc(folderName, fileName).ConfigureAwait(false);
                    stream = byteArr.ToStream();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("ImageCache - CacheImage() - Has Error: " + ex.Message.ToString());
            }
            return stream;
        }

        //下载图片
        public static async Task<Stream> DownloadFileAsync(string url,string fileName,string folderName)
        {
            byte[] byteArray = new byte[0];

            try
            {
                ScouterBackData scouterBackData = await new HttpQueryer()
                                                        .RequestStreamAsync(url)
                                                        .Fly(typeof(byte[]))
                                                        .ConfigureAwait(false);
                if (scouterBackData.IsSuccess)
                {
                    byteArray = (byte[])scouterBackData.ResponseData;
                }
                else
                {
                    throw new Exception(scouterBackData.Msg.ToString());
                }
                //判断保存是否成功
                //Debug.WriteLine("fileName:" + fileName);
                StorageHelper.SaveFileAsync(byteArray, fileName, folderName);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("ImageCache - DownloadFileAsync() - Has Error: Url:" + url + ex.Message.ToString());
            }
            return new MemoryStream(byteArray);
        }

        /// <summary>
        /// 图片地址转换成图片名称
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        internal static string UriToFileName(string url)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("uri is null");
            }
            if (url.Contains("?"))
            {
                url = url.Remove(url.IndexOf('?'));
            }
            string realImageName = url.Substring(url.LastIndexOf("/") + 1);
            return MD5Core.GetHashString(realImageName) + System.IO.Path.GetExtension(realImageName);
        }
    }
}
